Enterprise Objects Framework Release 1.1 Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

EODatabaseContext

Inherits From:	NSObject

Declared In:	eoaccess/EODatabaseContext.h

Class Description

An EODatabaseContext represents a single transaction scope on the database server, and determines the updating and locking strategy used by its EODatabaseChannel objects. A database context is managed by an EODatabase object, which represents the connection to the server. If the server supports multiple concurrent transaction sessions, the database object may have several database contexts. If the server and adaptor support it, a database context may in turn have several EODatabaseChannels, which handle access to the data on the server. A database context by default has no channels; to create a new channel, allocate and initialize one with initWithDatabaseContext:.

A database context creates an EOAdaptorContext when initialized, and uses this object to communicate with the database server.

Controlling Transactions

EODatabaseContext defines a simple set of messages for explicitly controlling transactions: beginTransaction, commitTransaction, and rollbackTransaction. Each of these messages confirms the requested action with the database context's delegate, then performs the action if possible. There's also a set of messages for notifying a database context that a transaction has been started, committed, or rolled back without the participation of the context, such as through direct communication with the server, through a stored procedure invoked by another object, and so on. You use these notification messages to keep a database context synchronized with the state of the server: transactionDidBegin, transactionDidCommit, and transactionDidRollback.

Updating And Locking Strategies

EODatabaseContext supports four updating strategies (one of which is actually a read-only strategy), defined by the EOUpdateStrategy type: EOUpdateWithOptimisticLocking, EOUpdateWithPessimisticLocking, EOUpdateWithNoLocking, and EONoUpdate. The following paragraphs describe each of the update strategies in detail. All three of the modes that support updating have the same behavior when snapshotting is not set for the parent database: They permit updates only for objects fetched within the same transaction.

EOUpdateWithOptimisticLocking is the default update strategy. Under optimistic locking, objects aren't locked immediately on being fetched from the server: Instead, whenever you attempt to update an object in the database, the object's snapshot is used to ensure that the values in the corresponding database row haven't changed since the object was fetched. As long as the snapshot matches the values in the database, the update is allowed to proceed. When snapshotting is set in the parent database, you can update objects even if they weren't fetched in the current transaction.

The EOUpdateWithPessimisticLocking strategy causes objects to be locked when they're selected. This ensures that no one else can modify the objects until the transaction ends. However, this doesn't necessarily mean that either the select or the update operation will succeed. Depending on the type of locking provided by the database server, you may not be allowed to select locked objects, you may be allowed to select but not update them, or you may be allowed to lock but still not update them (see your adaptor's documentation to find out what kind of locking is supported). If the context's EODatabase keeps snapshots, you can also update objects that you haven't fetched during the current transaction. Since those objects haven't been locked, however, the optimistic strategy is used.

The EOUpdateWithNoLocking strategy causes objects to be updated with no checking (this is sometimes called a ªblindº update). No comparisons are made between the snapshot and the row in the database to ensure that the values in the database haven't changed; they're simply overwritten with the new values. When snapshotting is set in the parent database, you can update objects even if they weren't fetched in the current transaction.

EONoUpdate is useful when you want to retrieve data with as little overhead as possible and don't need to perform updates. To reap the full benefits of this mode, snapshotting in the parent database should be turned off. When the context is in no-update mode and the parent database is not keeping snapshots, the least amount of overhead is used to get data into enterprise objects and back to the client program.

Propagation of Changes back to the EODatabase

An EODatabase holds the master view of uniqued enterprise objects; its view of the objects represents the state of all committed operations on the database server. While a transaction is in effect, some objects may be changed; these changes, though not committed, must be considered real for all operations involved in that transaction. To this end, an EODatabaseContext keeps its own snapshotting information for enterprise objects as they're inserted, updated, and deleted. The database context and its database channels use these snapshots instead of the EODatabase's until all pending transactions end. Only when all pending transactions for the EODatabaseContext are committed does it fold those changes back into the EODatabase's snapshots. If a database context's top-level transaction is rolled back, of course, all changes are simply discarded.

Instance Variables

None declared in this class.

Method Types

Initializing instances	- initWithDatabase:

Getting the adaptor context	- adaptorContext

Getting the database object	- database

Finding open channels	- hasBusyChannels

Controlling transactions	- beginTransaction
- commitTransaction
- rollbackTransaction

Notifying of other transactions	- transactionDidBegin
- transactionDidCommit
- transactionDidRollback

Nesting transactions	- canNestTransactions
- transactionNestingLevel

Setting the update strategy	- setUpdateStrategy:
- updateStrategy

Uniquing/snapshotting	- keepsSnapshots
- forgetObject:
- objectForPrimaryKey:entity:
- recordObject:primaryKey:snapshot:
- snapshotForObject:

Instance Methods

adaptorContext

- (EOAdaptorContext *)adaptorContext

Returns the EOAdaptorContext used by the EODatabaseContext for communication with the database server. Your application can interact directly with the EOAdaptorContext, but should change transaction state with the database context so that it remains synchronized with the database and with the adaptor context. If you change the transaction state with an adaptor context, you should use the transactionDidBegin, transactionDidCommit, and transactionDidRollback to keep the database context apprised of the changes.

beginTransaction

- (BOOL)beginTransaction

Attempts to begin a new transaction, nested within the current one if nested transactions are supported. Returns YES if successful and NO if not (specifically, if nested transactions aren't supported).

See also:  - transactionDidBegin, - canNestTransactions, - transactionNestingLevel, - commitTransaction, - rollbackTransaction

canNestTransactions

- (BOOL)canNestTransactions

Returns YES if the database server can nest transactions, NO otherwise.

See also:  - transactionNestingLevel

commitTransaction

- (BOOL)commitTransaction

Attempts to commit the last transaction begun, returning YES if successful and NO if not.

When an EODatabaseContext commits the top-level transaction (so that the nesting level becomes 0), it folds the snapshots of any updated objects back into its EODatabase.

See also:  - transactionDidCommit,- rollbackTransaction, - beginTransaction, - transactionNestingLevel

database

- (EODatabase *)database

Returns the EODatabase that the context works with.

See also:  - initWithDatabase:

forgetObject:

- (void)forgetObject:anEO

Removes anEO from the EODatabaseContext's uniquing tables and destroys its snapshot with respect to the EODatabaseContext. Doesn't affect equivalent information kept by the EODatabase until the top-level transaction is committed; then, the EODatabaseContext sends the EODatabase a forgetObject: message for anEO. Raises NSInvalidArgumentException if anEO is nil or if there's no transaction in progress, and raises NSInternalInconsistencyException if anEO is a fault (see the EOFault class specification for information).

See also:  - forgetObject: (EODatabase)

hasBusyChannels

- (BOOL)hasBusyChannels

Returns YES if the receiver has any EODatabaseChannels with fetches in progress, NO otherwise.

See also:  - isFetchInProgress (EODatabaseChannel)

initWithDatabase:

- initWithDatabase:(EODatabase *)aDatabase

Initializes a newly allocated EODatabaseChannel with aDatabase as the EODatabase object it works with. The new EODatabaseContext retains aDatabase. Returns self, or nil if no more contexts can be associated with aDatabase. This is the designated initializer for the EODatabaseContext class.

See also:  - database

keepsSnapshots

- (BOOL)keepsSnapshots

Returns NO if the EODatabaseContext's locking strategy is EONoUpdate and the parent EODatabase doesn't keep snapshots; returns YES otherwise. EODatabaseContexts nearly always keep local snapshots.

See also:  - keepsSnapshots (EODatabase)

objectForPrimaryKey:entity;

- objectForPrimaryKey:(NSDictionary *)aKey entity:(EOEntity *)anEntity

Returns the unique enterprise object for aKey and anEntity, or nil if one doesn't exist.

See also:  - objectForPrimaryKey: (EODatabase)

recordObject:primaryKey:snapshot:

- (void)recordObject:anEO
primaryKey:(NSDictionary *)aKey
snapshot:(NSDictionary *)aSnapshot

Records anEO and aSnapshot under aKey with respect to the EODatabaseContext. Raises NSInvalidArgumentException under any of the following conditions:

·	No transaction is in progress.
·	When uniquing and either anEO or aKey is nil.
·	When uniquing and anEO is an EOFault.
·	When context keeps snapshots and aSnapshot is nil.

There may already be a unique instance recorded for anEO's key, so you shouldn't expect that the object you pass in to this method can be shared. To get the unique enterprise object created for anEO, use objectForPrimaryKey:entity:.

Changes to an EODatabaseContext's snapshots are folded back into its parent EODatabase when the top-level transaction is committed.

See also:  - recordObject:primaryKey:snapshot: (EODatabase), - commitTransaction

rollbackTransaction

- (BOOL)rollbackTransaction

Attempts to roll back the last nested transaction in progress, returning YES if successful and NO if not.

See also:  - transactionDidRollback, - commitTransaction, - beginTransaction

setUpdateStrategy:

- (void)setUpdateStrategy:(EOUpdateStrategy)strategy

Set the update strategy used by the EODatabaseContext to strategy. See the class description for information on update strategies. Raises NSInvalidArgumentException if the context has any transactions in progress.

See also:  - transactionNestingLevel

snapshotForObject:

- (NSDictionary *)snapshotForObject:anEO

Returns the snapshot associated with anEO, if there is one; otherwise returns nil.

See also:  - snapshotForObject: (EODatabase)

transactionDidBegin

- (void)transactionDidBegin

Informs the EODatabaseContext and its EOAdaptorContext that the server has begun a transaction (for example, as the result of a stored procedure). This method allows the EODatabaseContext to maintain a valid state with regard to the server. Your application should invoke this method whenever it begins a transaction in the database server in any way other than by sending the database context a beginTransaction message (for example, by using EOAdaptorChannel's evaluateExpression:).

transactionDidCommit

- (void)transactionDidCommit

Informs the EODatabaseContext and its EOAdaptorContext that the server has committed a transaction (for example, as the result of a stored procedure). This method allows the EODatabaseContext to maintain a valid state with regard to the server. Your application should invoke this method whenever it commits a transaction in the database server in any way other than by sending the database context a commitTransaction message (for example, by using EOAdaptorChannel's evaluateExpression:).

When an EODatabaseContext commits the top-level transaction (so that the nesting level becomes 0), all changes made to the context's snapshots are folded back into the context's EODatabase.

transactionDidRollback

- (void)transactionDidRollback

Informs the EODatabaseContext and its EOAdaptorContext that the database has rolled back a transaction (for example, as the result of a stored procedure). This method allows the EODatabaseContext to maintain a valid state with regard to the server. Your application should invoke this method whenever it rolls back a transaction in the database server in any way other than by sending a rollbackTransaction message (for example, by using EOAdaptorChannel's evaluateExpression:). It should also invoke this method when a transaction is rolled back by a trigger, a stored procedure, or by the server itself due to an error condition such as a deadlock.

transactionNestingLevel

- (unsigned int)transactionNestingLevel

Returns the number of transactions in progress. If the EODatabaseContext's adaptor supports nested transactions, this number may be greater than 1.

See also:  - canNestTransactions

updateStrategy

- (EOUpdateStrategy)updateStrategy

Return the update strategy used by the EODatabaseContext. The default strategy is EOUpdateWithOptimisticLocking. See the class description for information on update strategies.